home *** CD-ROM | disk | FTP | other *** search
- ;-------------------------------------------------------------------------------
- ;Tries to return PID of process specified by ProcName.
- ;Returns PIDERROR if there was error in memory allocation or snapshot
- ;creation or process was not found.
- ;ProcName can be: "process.exe","PathTo\process.exe" or special names
- ;like: "System" or (NT5+) "[System Process]".
- ;ProcName must be ANSI string.
- ;In NT5+ (Win2K+) is used NtQuery only if ProcName was "PathTo\process.exe"
- ;otherwise is used Toolhelp32 (supports NT5+ special names.
-
- FindProcessNT5 PROC USES EBX ESI EDI, ProcName
- LOCAL NamePos :DWORD
- LOCAL ModEntry0 :PEB_MODULE_ENTRY0
- LOCAL CandName :DWORD
- LOCAL MMbase :DWORD
- LOCAL StartStop :DWORD
- LOCAL pbi :PROCESS_BASIC_INFORMATION
- LOCAL process :PROCESSENTRY32
- LOCAL PIDarray[MAX_PIDs] :DWORD
- LOCAL ModName[MAX_PATH] :WCHAR
- LOCAL ModName2[MAX_PATH] :WCHAR
-
- ;-----------------------------------------------
- ; Do primitive MultiByteToWideChar:
- ; ProcName -> ModName
- MOV EAX, ProcName
- MOV NamePos, EAX
- LEA EDI, ModName
- MOV ESI, ProcName
- XOR EAX, EAX
- MOV CandName, EDI
- NChar:
- LODSB
- STOSW
- CMP AL, "\"
- JNE @F
- MOV CandName, EDI ;dest base name: process.exe
- MOV NamePos, ESI ;src base name
- @@:
- TEST AL, AL
- JNE NChar
- ;-----------------------------------------------
- MOV EAX, W32Version
- TEST EAX, EAX
- JS DoW9X
- CMP AL, 4 ;NT4- has NtQuery only
- JBE DoNT4
- MOV ECX, NamePos
- CMP ECX, ProcName ;if there was NOT PathTo then NamePos == ProcName
- JE DoW9X ;and then use Toolhelp32
- ;-----------------------------------------------
- DoNT4:
- ;Do usual things: allocate memory, call ntquery, ...
- oMOV EBX, START_SIZE_FOR_NTQUERY
-
- @@:
- iWin32 VirtualAlloc, NULL, EBX, MEM_COMMIT, PAGE_EXECUTE_READWRITE
- TEST EAX, EAX
- JE FNT4NoMem
- MOV ESI, EAX
- sWin32 NtQuerySystemInformation, SystemProcessInformation, ESI, EBX, NULL
- CMP EAX, STATUS_INFO_LENGTH_MISMATCH
- JNE @F
- iWin32 VirtualFree, ESI, NULL, MEM_RELEASE
- ADD EBX, DELTA_SIZE_FOR_NTQUERY
- JMP @B
- @@:
- SUB EDI, EDI ;PID counter = 0
- TEST EAX, EAX
- JL FNT4BadNTQSI ;native api returned NTSTATUS
- ;-----------------------------------------------
- FindBaseNames:
- MOV EBX, ESI
- ASSUME EBX: PTR SYSTEM_PROCESS_INFORMATION
- JMP @F
- NextProc:
- CMP [EBX].SizeOfBlock, 0 ;if ==0 info ends
- JE ProcInfoEnd
- ADD EBX, [EBX].SizeOfBlock ;to the next block
- @@:
- MOV EDX, [EBX].ProcessName.Buffer
- MOVZX ECX, [EBX].ProcessName.Length_
- TEST EDX, EDX ;NULL pointer (Idle process)
- JE NextProc
- AND WCHAR PTR [EDX+ECX], 0 ;for sure put zero at the end of unicode string
- iWin32 lstrcmpiW, EDX, CandName ;compare base names
- TEST EAX, EAX
- JNE NextProc
- CMP EDI, MAX_PIDs ;maximum candidates
- JAE ProcInfoEnd
- oMOV PIDarray[EDI*4], [EBX].ProcessId
- INC EDI ;++ PID counter
- JMP NextProc
- ASSUME EBX: NOTHING
- ;-----------------------------------------------
- ProcInfoEnd:
- FNT4BadNTQSI:
- ;free buffer for ntquery
- iWin32 VirtualFree, ESI, NULL, MEM_RELEASE
- TEST EDI, EDI ;edi == 0 if alloc error or no candidate
- JE FNT4NoProc
-
- MOV ECX, CandName
- LEA EDX, ModName
- MOV EAX, PIDarray[EDI*4-4] ;PID of the last candidate (the last == the youngest)
- CMP ECX, EDX ;if ProcessName was without PathTo
- JE ProcessFound ;we're done
- ;-----------------------------------------------
- ;ProcessName was "PathTo\process.exe"
- ;Complex technique must be used.
- ;Take candidate from last to 1st and if module names are equal return PID.
-
- FindModuleFileName:
- iMOV EBX, ReadProcessMemory
- NextCnd1:
- DEC EDI
- JL FMFNdone ;no more candidates
- ;open candidate
- iWin32 OpenProcess, PROCESS_QUERY_INFORMATION OR PROCESS_VM_READ,\
- FALSE,\
- PIDarray [EDI*4]
- TEST EAX, EAX
- JE NextCnd1 ;can't open go next
- ;-----------------------------------------------
- PUSH PIDERROR ;prepare return code
- MOV ESI, EAX ;hProcess
- LEA ECX, pbi ;buffer for NtQuery
- sWin32 NtQueryInformationProcess, ESI, ProcessBasicInformation, ECX, SIZEOF pbi, NULL
- TEST EAX, EAX
- JL FNT4CloseProc ;native api returned NTSTATUS
- ;-----------------------------------------------
- MOV EAX, pbi.PebBaseAddress
- PUSH ECX ;place for image base
- PUSH ECX ;place for pProcParameters
- MOV EDX, ESP
- ADD EAX, PEB.MainImageBase ;EAX now points to the image base of main module in candidate process
- sWin32 EBX, ESI, EAX, EDX, 4+4, NULL ;read both image base and pProcParameters
- TEST EAX, EAX
- POP EAX ;image base
- POP ECX ;pProcParameters
- JE FNT4CloseProc ;ReadMemory failed
- JECXZ FNT4CloseProc ;pProcParameters == NULL -> process is not initialized
- ADD ECX, PROCESS_PARAMETERS.pFirstModEntry0
- MOV MMbase, EAX ;main module base
- LEA EDX, StartStop
- sWin32 EBX, ESI, ECX, EDX, 4, NULL ;read pFirstModEntry0 to StartStop
- TEST EAX, EAX
- JE FNT4CloseProc
- ;-----------------------------------------------
- ;walk thru ModEntry0 chain and compare ImageBase with MainModuleImageBase
- ;== search for main module
- ;ModEntries are in round queue (last points to 1st)
-
- MOV EAX, StartStop
- JMP @F
- NextMod:
- CMP EAX, StartStop
- JE FNT4CloseProc
- @@:
- LEA EDX, ModEntry0
- sWin32 EBX, ESI, EAX, EDX, SIZEOF ModEntry0, NULL
- TEST EAX, EAX
- JE FNT4CloseProc ;can't read ModuleEntry0
- MOV ECX, MMbase
- MOV EAX, ModEntry0.pNextModEntry0
- CMP ECX, ModEntry0.ImageBase ;compare bases
- JNE NextMod
- ;-----------------------------------------------
- ;main module entry was read into ModEntry0
- NameFirst1:
- LEA EDX, ModName2 ;here read full candidate name
- MOVZX ECX, ModEntry0.ModuleFileName.Length_ ;how much bytes
- PUSH EDX
- PUSH ECX
- sWin32 EBX, ESI, ModEntry0.ModuleFileName.Buffer, EDX, ECX, NULL
- TEST EAX, EAX
- POP ECX ;length
- POP EDX ;full name
- JE FNT4CloseProc ;can't read
- LEA EAX, ModName
- AND WCHAR PTR [EDX+ECX], 0 ;for sure 0 at the end of buffer
- iWin32 lstrcmpiW, EDX, EAX ;compare full names
- TEST EAX, EAX
- JNE FNT4CloseProc ;no match -> try next process
- POP ECX ;remove prepared return code
- PUSH PIDarray[EDI*4] ;put new return code: PID of candidate
- FNT4CloseProc:
- iWin32 CloseHandle, ESI ;close used process
- POP EAX
- CMP EAX, PIDERROR
- JNE ProcessFound ;success -> return PID
- NextCnd:
- JMP NextCnd1 ;try next process
- FNT4NoProc:
- FNT4NoMem:
- FMFNdone:
- oMOV EAX, PIDERROR ;some error or can't find matching process
- ProcessFound:
- JMP Fin0
- ;-----------------------------------------------
- ;9x and NT5+ (if there was not PathTo) part:
- ;do standard Toolhelp32 things and work with ANSI strings
-
- DoW9X:
- oMOV EDI, PIDERROR ;prepare return code
- LEA ESI, process
- ASSUME ESI: PTR PROCESSENTRY32
- sWin32 CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
- MOV EBX, EAX
- CMP EAX, EDI ; -1 == PIDERROR
- JE Fin0
-
- MOV [ESI].dwSize, PROCESSENTRY32 ; a must
- sWin32 Process32First, EBX, ESI
- CheckProc:
- TEST EAX, EAX
- JE Fin
- LEA EAX, [ESI].szExeFile ;always Ansi (but NT5+ has Process32FirstW/NextW)
-
- MOV ECX, NamePos
- MOV EDX, EAX
- CMP ECX, ProcName
- JE @F ;if ProcName doesn't contain PathTo\ ....
- MOV ECX, ProcName
- JMP CompareWithPath ;else do this
-
- @@:
- CMP ACHAR PTR [EAX], 0 ;string ends?
- JE @F
- CMP ACHAR PTR [EAX], "\"
- JE @Fond
- INC EAX
- JMP @B
- @Fond:
- INC EAX
- MOV EDX, EAX ;... base name in szExeFile must be found
- JMP @B
- @@:
-
- CompareWithPath:
- iWin32 lstrcmpiA, EDX, ECX
- TEST EAX, EAX
- JNE @F
- MOV EDI, [ESI].th32ProcessID ;if names are equal then EDI = PID
- @@:
- sWin32 Process32Next, EBX, ESI
- JMP CheckProc ;find last process with matching name
- ASSUME ESI: NOTHING
- Fin:
- iWin32 CloseHandle, EBX ;destroy snapshot
- MOV EAX, EDI
- Fin0:
- RET
- FindProcessNT5 ENDP
- ;-------------------------------------------------------------------------------
- ;Builds list of current process identifiers. User must supply buffer (pPIDs)
- ;and its size (SizeInPIDs) in dwords.
- ;Returns PIDERROR if there was error in memory allocation or snapshot
- ;creation. Otherwise returns number of current PIDs. If the returned value
- ;is greater than SizeInPIDs, caller has to provide larger buffer.
- ;In NT5+ (Win2K+) is used NtQuery instead of Toolhelp32 because of speed.
-
- BuildPIDList PROC USES EBX ESI EDI, pPIDs, SizeInPIDs
- LOCAL process :PROCESSENTRY32
-
- ;1st determine OS: if Win9x -> Toolhelp32, if NT -> NtQuery
- MOV EDI, pPIDs ;STOSD will be used
- MOV EAX, W32Version
- TEST EAX, EAX
- JS DoW9Xp
-
- ;-----------------------------------------------
- ;NT part:
- oMOV EBX, START_SIZE_FOR_NTQUERY
- @@:
- iWin32 VirtualAlloc, NULL, EBX, MEM_COMMIT, PAGE_EXECUTE_READWRITE
- MOV ESI, EAX
- DEC EAX ;NULL -> PIDERROR ;because in user mode NT is any memo < 80000000H
- JL Fin
- sWin32 NtQuerySystemInformation, SystemProcessInformation, ESI, EBX, NULL
- CMP EAX, STATUS_INFO_LENGTH_MISMATCH ;too little memory?
- JNE @F
- iWin32 VirtualFree, ESI, NULL, MEM_RELEASE ;yes free and alloc more
- ADD EBX, DELTA_SIZE_FOR_NTQUERY
- JMP @B
- @@:
- TEST EAX, EAX
- JL QueryOrAllocFailed ;native api returned NTSTATUS
- ;-----------------------------------------------
- MOV EBX, ESI
- ASSUME EBX: PTR SYSTEM_PROCESS_INFORMATION
- SUB ECX, ECX ;PID counter = 0
- JMP @F
- NextProc:
- CMP [EBX].SizeOfBlock, 0 ;size ==0 -> info ends
- JE NTPIDsDone
- ADD EBX, [EBX].SizeOfBlock
- @@:
- CMP ECX, SizeInPIDs
- JGE @F ;must not exceed size of the buffer
- MOV EAX, [EBX].ProcessId
- STOSD
- @@:
- INC ECX ; ++PID counter
- JMP NextProc
- ASSUME EBX: NOTHING
-
- QueryOrAllocFailed:
- oMOV ECX, PIDERROR
-
- NTPIDsDone:
- PUSH ECX
- iWin32 VirtualFree, ESI, NULL, MEM_RELEASE ;free memory for ntquery
- POP EAX
- JMP Fin
- ;-----------------------------------------------
- ;9x part:
- DoW9Xp:
- ;create process snapshot:
- LEA ESI, process
- ASSUME ESI: PTR PROCESSENTRY32
- sWin32 CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
- MOV EBX, EAX
- CMP EAX, -1 ;-1 == PIDERROR
- JE Fin
-
- ;do process32first and then repeat process32next until it returns NULL:
- oMOV [ESI].dwSize, PROCESSENTRY32
- sWin32 Process32First, EBX, ESI
- SUB ECX, ECX
- CheckProc:
- TEST EAX, EAX
- JE FreeSnapshot
- CMP ECX, SizeInPIDs
- JGE @F
- MOV EAX, [ESI].th32ProcessID
- STOSD
- @@:
- INC ECX
- PUSH ECX
- sWin32 Process32Next, EBX, ESI
- POP ECX
- JMP CheckProc
- ASSUME ESI: NOTHING
-
- FreeSnapshot:
- PUSH ECX
- iWin32 CloseHandle, EBX ;close snapshot
- POP EAX
-
- Fin:
- RET
- BuildPIDList ENDP
- ;-------------------------------------------------------------------------------